## hcquant
# 下载服务器上的择时信号

from .path import *
from .timinglist import *
import requests
import json
import pandas as pd
import datetime
from ..calendar import *
from dateutil.parser import parse
import tushare as ts
import datetime as dt
today = dt.datetime.now().strftime('%Y%m%d')



def unix2time(x):
    return datetime.datetime.fromtimestamp(x/1000).strftime("%Y%m%d")

# 交易日获取函数
# def get_tradeday():
#     sql="""
#         select TRADE_DAYS as calendarDate from AShareCalendar where S_INFO_EXCHMARKET='SSE' and TRADE_DAYS<='{0}'  order by TRADE_DAYS
#     """.format(today)
#     df = pd.read_sql(sql, wind_engine)
#     return df

# 交易日调整函数，向前向后移动
def timing_step_trade_date(date, step, df = 0, astype='%Y%m%d'):
    """
    交易日向前向后漂移
    返回 '%Y-%m-%d'
    """
    # alldays = get_tradeday()
    date = parse(date).strftime('%Y%m%d') if isinstance(date, str) else date.strftime('%Y%m%d')
    if step == 0:
        return parse(date).strftime(astype)
    else:
        # df = get_tradeday()
        if step > 0:
            df = df.loc[df['calendarDate'] > date]
            return parse(df['calendarDate'].iloc[step-1]).strftime(astype)
        elif step < 0:
            df = df.loc[df['calendarDate'] < date]
            return parse(df['calendarDate'].iloc[step]).strftime(astype)


def timingdownSingal():
    # timingdict
    print('Start downloading from HCQUANT.COM')

    for ver in timingdict.keys():
        for file in timingdict[ver]:
            # print(ver,file)
            try:
                r=requests.get('http://t.hcquant.com/{0}/{1}'.format(ver,file))
                tdict=eval(r.content)
                eq=pd.DataFrame(tdict['data'],columns=['trade_dt','open','high','low','close','vol'])
                bedate=pd.DataFrame(tdict['betime'],columns=['bdate','edate'])
                eq['trade_dt']=eq['trade_dt'].apply(lambda x:unix2time(x))
                bedate['bdate']=bedate['bdate'].apply(lambda x:unix2time(x))
                bedate['edate']=bedate['edate'].apply(lambda x:unix2time(x))
                eq.to_msgpack(TIMING_PATH+r'\{0}\eq_{1}.pack'.format(ver,file))
                bedate.to_msgpack(TIMING_PATH+r'\{0}\bdate_{1}.pack'.format(ver,file))
                with open(TIMING_PATH+r'\{0}\{1}'.format(ver,file), 'w') as f:
                    json.dump(tdict, f)
            except:
                pass

    print('Downloading from HCQUANT.COM Finished!')


def timing_deal(ver='v5',code='000001'):
    timingPath=HOME_PATH+r'\timing'
    dataPath=timingPath+ r'/' + ver
    print('Current Working Folder:'+ dataPath)
    print('正在帮您提取历史行情与择时信号，请耐心等待！')
    # get bedate data :
    bedate=pd.read_msgpack(dataPath+'/bdate_{0}.json.pack'.format(code))
    # get eq data:
    eq=pd.read_msgpack(dataPath+'/eq_{0}.json.pack'.format(code))
    # bdate 后移一个交易日 edate后移两个交易日
    df = get_tradeday()
    bedate['bdate_real'] = bedate.bdate.apply(lambda x:timing_step_trade_date(date=x,step=1,df=df))
    bedate['edate_real'] = bedate.edate.apply(lambda x:timing_step_trade_date(date=x,step=2,df=df))
    # eq 处理
    eq.set_index('trade_dt', inplace=True)
    eq['signal'] = 0
    print('最新择时信号日期为：'+ eq.index[-1])
    # 循环添加信号
    for k in range(bedate.shape[0]):
        eq.loc[bedate.ix[k, 'bdate_real']:bedate.ix[k, 'edate_real'], 'signal'] = 1
    print('提取完毕！')
    return eq


def plottiming(df) :
    import pyecharts.options as opts
    # from example.commons import Faker
    from pyecharts.charts import Line
    df['benchmark'] = df.close/df.close[0]
    df['ret'] = df.close.pct_change()
    df['timingret'] = df['ret']*df['signal']+1
    df['strategy'] = 1*df['timingret'].cumprod()
    df.dropna(inplace=True)
    xaxis=df.index.tolist()
    strategy=df['strategy'].tolist()
    benchmark=df['benchmark'].tolist()

    def line_base() -> Line:
        c = (
            Line()
                .add_xaxis(xaxis)
                .add_yaxis("Strategy", strategy, label_opts=opts.LabelOpts(is_show=False))
                .add_yaxis("Benchmark", benchmark, label_opts=opts.LabelOpts(is_show=False))
                .set_global_opts(title_opts=opts.TitleOpts(title="择时效果展示"))

        )
        return c

    c = line_base()
    # c.render_notebook()
    return c